#ifndef __I_PE_DASM__
#define __I_PE_DASM__

#include "hdex64.h"

namespace xm
{
	DEFINE_PROGID(WinPETools);
	DEFINE_PROGID(WinPEThunkFetcher);

	enum DASM_TRACE_OPTIONS
	{
		DTO_JMP			= 1,
		DTO_CALL		= 2,
		DTO_JCC_T		= 4,
		DTO_BRACH_FIRST = 8,
		DTO_ZERO_BREAK	= 0x10,
		DTO_RVA_ONCE	= 0x20,
		DTO_EX_INS		= 0x80000,
	};

	enum DASM_TRACE_EVENT
	{
		DTE_BRANCH,
	};

	enum X64INSTFLAG
	{
		IX64F_X64 = 1,
	};

	struct X64INST
	{
		UINT32	RVA;
		UINT32	OpCode;
		UINT8	InsLen;
		UINT8	ModRMRLen;
		UINT8	Flag;
	};

	struct X64INSTEX : X64INST
	{
		union {
			hde32s	i32;
			hde64s	i64;
		} mix;
	};

	//DEFINE_PROGID(PEDisAsmX64);

	struct IPEDisAsmCallback
	{
		STDMETHOD(OnEvent)( DASM_TRACE_EVENT uEvent ) PURE;
		STDMETHOD(OnInstruction)( X64INST * lpInst ) PURE; 
	};

	//class IKPEDisAsm : public IUnknown
	//{
	//public:
	//	STDMETHOD(Init)( IUnknown * arch_or_tool ) PURE;
	//	STDMETHOD(FetchBIL)( UINT32 rva, SIZE_T options, IPEDisAsmCallback * callback ) PURE;
	//	STDMETHOD(Close)() PURE;
	//	DECLARE_IID;
	//};

	//// {25DB3DBD-05AF-4E93-9D1A-933F10468F68}
	//DEFINE_IID( IKPEDisAsm, "{25DB3DBD-05AF-4E93-9D1A-933F10468F68}",
	//	0x25db3dbd, 0x5af, 0x4e93, 0x9d, 0x1a, 0x93, 0x3f, 0x10, 0x46, 0x8f, 0x68);

	enum MATCH_MODE_T
	{
		KeyStrInModuleName = -1,
		KeyStrEqulModuleName = 0,
		ModuleNameInKeyStr = 1,
	};

	class IKPETools : public IUnknown
	{
	public:
		struct IMPITEM
		{
			UINT32	iat;
			LPCSTR	api;
			LPCSTR	dll;
			UINT32	crc;
		};
		struct IMPNAME
		{
			UINT32	namrva;
			UINT32	iat;
		};
	public:
		STDMETHOD(Init)( IPeReader * ope ) PURE;
		STDMETHOD_(IPeReader *, WinPeObject)() PURE;
		STDMETHOD_(SIZE_T, ImpGetCount)() PURE;
		STDMETHOD_(IMPITEM*, ImpGetAt)( SIZE_T idx = 0 ) PURE;
		STDMETHOD_(IMPITEM*, ImpFindByIAT)( UINT64 addr, BOOL is_va = FALSE ) PURE;
		STDMETHOD_(UINT32, ImpFindByName)( UINT32 namerva ) PURE;
		//////////////////////////////////////////////////////////////////////////
		STDMETHOD(FetchBIL)( UINT32 rva, SIZE_T options, IPEDisAsmCallback * callback ) PURE;
		//////////////////////////////////////////////////////////////////////////
		STDMETHOD_(VOID,Close)() PURE;
		STDMETHOD_(LPCSTR, IsMoudleImported)( LPCSTR aName, MATCH_MODE_T bStrstr = KeyStrEqulModuleName ) PURE;
		DECLARE_IID;
	};

	// {A1C6D3F9-B9C1-43D2-9BA2-49A463B5FA53}
	DEFINE_IID( IKPETools, "{A1C6D3F9-B9C1-43D2-9BA2-49A463B5FA53}",
		0xa1c6d3f9, 0xb9c1, 0x43d2, 0x9b, 0xa2, 0x49, 0xa4, 0x63, 0xb5, 0xfa, 0x53);

	enum TRUNK_CLS 
	{
		PE_TRUNK_API = 1,
		PE_TRUNK_STRA = 2,
		PE_TRUNK_STRW = 4,

		PE_TRUNK_ALL = PE_TRUNK_API|PE_TRUNK_STRA|PE_TRUNK_STRW,
	};

	struct TRUNK_ITEM
	{
		TRUNK_CLS			kls;
		SIZE_T				uniq;
		UINT64				fpos;
		LPCSTR				txt;
		BOOL				call;
	};

	class IKTrunkFetcher : public IUnknown
	{
	public:
		STDMETHOD(Open)( IUnknown * archp ) PURE;
		STDMETHOD(Close)() PURE;
		STDMETHOD(Fetch)( SIZE_T klsmask ) PURE;
		STDMETHOD_(LPCSTR,GetAsText)() PURE;
		STDMETHOD_(SIZE_T,GetCount)() PURE;
		STDMETHOD(GetItem)( SIZE_T idx, TRUNK_ITEM * lpItem ) PURE;
		STDMETHOD(GetPSH)( UINT8 * lpMD5 ) PURE;
		DECLARE_IID;
	};

	// {4A2EEF68-D914-4742-BA54-D6DFB515D2AF}
	DEFINE_IID( IKTrunkFetcher, "{4A2EEF68-D914-4742-BA54-D6DFB515D2AF}",
		0x4a2eef68, 0xd914, 0x4742, 0xba, 0x54, 0xd6, 0xdf, 0xb5, 0x15, 0xd2, 0xaf);

};



#endif